#ifndef PROTOMSG_VALUE_H_
#define PROTOMSG_VALUE_H_
#include "protomsg_config.h"

namespace protomsg {
  class Enumerator;
  // Protocol message value is a class which 
  // holds different type of value internally
  class Value {
  public:
    // This is the default ctor of Value
    Value():value_.enum_value_ptr(NULL) , owner_(false) {}
    // Constructing using other stuff instead of internally
    Value( const TargetCppType< PROTOMSG_ENUM >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_FINT32 >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_FINT64 >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_MESSAGE >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_REAL >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_BOOLEAN >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    Value( const TargetCppType< PROTOMSG_INT >::ptr_type val ) 
      : value_.enum_value_ptr(val) , owner_(false) {}
    // Constructing using specified way 

  private:
    // Using a union struct to represent different type of
    // value internally , however , we do not really store
    // the value , instead we store the pointer of each value
    // and point to the real value which will help us not
    // to deal with the memory stuff .
    union {
      TargetCppType< PROTOMSG_ENUM >::ptr_type enum_value_ptr;
      TargetCppType< PROTOMSG_FINT32>::ptr_type fint32_value_ptr;
      TargetCppType< PROTOMSG_FINT64>::ptr_type fint64_value_ptr;
      TargetCppType< PROTOMSG_MESSAGE>::ptr_type message_value_ptr;
      TargetCppType< PROTOMSG_REAL>::ptr_type real_value_ptr;
      TargetCppType< PROTOMSG_BOOLEAN>::ptr_type boolean_value_ptr;
      TargetCppType< PROTOMSG_INT>::ptr_type int_value_ptr;
    } value_ ;
    // If the memory is allocated by this Value class 
    // the owner_ will set to true , otherwise , the Value
    // class will not take care of the memory stuff .
    bool owner_;
  };


}


#endif// PROTOMSG_VALUE_H_